.text
.align 8
.section .rodata
.LC0:
	.string	"Enter name of destination file:"
.LC1:
	.string	"a+"
.LC2:
	.string	"Cannot open %s\n"
.LC3:
	.string	"Cannot create output buffer\n"
.LC4:
	.string	"Enter name of first source file (empty line to quit):"
.LC5:
	.string	"Cannot append file to itself\n"
.LC6:
	.string	"r"
.LC7:
	.string	"Cannot create input buffer\n"
.LC8:
	.string	"Error in reading file %s.\n"
.LC9:
	.string	"Error in writing file %s.\n"
.LC10:
	.string	"File %s appended.\n"
.LC11:
	.string	"Next file (empty line to quit):"
.LC12:
	.string	"Done appending.%d files appended.\n"
.LC13:
	.string	"%s contents:\n"
.LC14:
	.string	"Done displaying."

.text
.globl main
.type main, @function
main:
    pushq %rbp
    movq %rsp, %rbp

    subq $192, %rsp
    // 分配局部变量
    // fa: -8(%rbp) /* fa */
    // fs: -16(%rbp) /* fs */
    // files: -20(%rbp) /* files */
    // file_app: -101(%rbp) /* file_app */
    // file_src: -182(%rbp) /* file_src */
    // ch: -186(%rbp) /* ch */
    movl $0, -20(%rbp) /* files */
    leaq .LC0(%rip), %rdi
    call puts

    leaq -101(%rbp) /* file_app */, %rdi
    movl $81, %esi
    call s_gets

    leaq -101(%rbp) /* file_app */, %rdi
    leaq .LC1(%rip), %rsi
    call fopen
    movq %rax, -8(%rbp) /* fa */

    cmpq $0, %rax
    jne .FILE_OPEN_SUCCESS
.FILE_OPEN_FAILED:
    leaq stderr(%rip), %rdi
    leaq .LC2(%rip), %rsi
    leaq -101(%rbp) /* file_app */, %rdx
    call fprintf
    movl $1, %edi
    call exit
.FILE_OPEN_SUCCESS:
    movq -8(%rbp) /* fa */, %rdi
    movq $0, %rsi
    movl $0, %edx
    movq $4096, %rcx
    call setvbuf
    cmpl $0, %eax
    je .SET_V_BUF_SUCCESS
.SET_V_BUF_FAILED:
    leaq .LC3(%rip), %rdi
    leaq stderr(%rip), %rax
    movq (%rax), %rsi
    call fputs
    movl $1, %edi
    call exit
.SET_V_BUF_SUCCESS:
    leaq .LC4(%rip), %rdi
    call puts
    jmp .WHILE_31_COMPARE
.WHILE_31_ENTER:
    leaq -182(%rbp) /* file_src */, %rdi
    leaq -101(%rbp) /* file_app */, %rsi
    call strcmp
    cmpl $0, %eax
    je .FILE_SRC_APP_SAME
    leaq -182(%rbp) /* file_src */, %rdi
    leaq .LC6(%rip), %rsi
    call fopen
    movq %rax, -16(%rbp) /* fs */
    cmpq $0, %rax
    je .OPEN_FILE_FAILED
    movq -16(%rbp) /* fs */, %rdi
    movl $0, %esi
    movl $0, %edx
    movq $4096, %rcx
    call setvbuf
    cmpl $0, %eax
    jne .SET_V_BUF_TGT_FAILED
    movq -16(%rbp) /* fs */, %rdi
    movq -8(%rbp) /* fa */, %rsi
    call append
.CHECK_FS_ERROR:
    movq -16(%rbp) /* fs */, %rdi
    call ferror
    cmpl $0, %eax
    je .CHECK_FA_ERROR
.FS_ERR:
    leaq stderr(%rip), %rdi
    leaq .LC8(%rip), %rsi
    leaq -182(%rbp) /* file_src */, %rdx
    call fprintf
.CHECK_FA_ERROR:
    movq -8(%rbp) /* fa */, %rdi
    call ferror
    cmpl $0, %eax
    je .FCLOSE
.FA_ERR:
    leaq stderr(%rip), %rdi
    leaq .LC9(%rip), %rsi
    leaq -101(%rbp) /* file_app */, %rdx
    call fprintf
.FCLOSE:
    movq -16(%rbp) /* fs */, %rdi
    call fclose
    incl -20(%rbp) /* files */
    leaq .LC10(%rip), %rdi
    leaq -182(%rbp) /* file_src */, %rsi
    movl $0, %eax
    call printf
    leaq .LC11(%rip), %rdi
    call puts
    jmp .WHILE_31_INCR
.SET_V_BUF_TGT_FAILED:
    leaq .LC7(%rip), %rdi
    leaq stderr(%rip), %rax
    movq 0(%rax), %rsi
    call fputs
    jmp .WHILE_31_INCR
.OPEN_FILE_FAILED:
    leaq stderr(%rip), %rax
    movq 0(%rax), %rdi
    leaq .LC2(%rip), %rsi
    leaq -182(%rbp) /* file_src */, %rdx
    call fprintf
    jmp .WHILE_31_INCR
.FILE_SRC_APP_SAME:
    leaq .LC5(%rip), %rdi
    leaq stderr(%rip), %rax
    movq 0(%rax), %rsi
    call fputs
    jmp .WHILE_31_INCR
.WHILE_31_INCR:
    // nothing to do 
.WHILE_31_COMPARE:
    leaq -182(%rbp) /* file_src */, %rdi
    movl $81, %esi
    call s_gets
    cmpq $0, %rax
    je .WHILE_31_END
    leaq -182(%rbp) /* file_src */, %rax
    movb 0(%rax), %al
    cmpb $0, %al
    je .WHILE_31_END
    jmp .WHILE_31_ENTER
.WHILE_31_END:

    leaq .LC12(%rip), %rdi
    movl -20(%rbp) /* files */, %esi
    movl $0, %eax
    call printf

    movq -8(%rbp) /* fa */, %rdi
    call rewind

    leaq .LC13(%rip), %rdi
    leaq -101(%rbp) /* file_app */, %rsi
    movl $0, %eax
    call printf

    jmp .WHILE_60_COMPARE
.WHILE_60_ENTER:
    movl -186(%rbp) /* ch */, %edi
    call putchar
.WHILE_60_INCR:
    // nothing to do 
.WHILE_60_COMPARE:
    movq -8(%rbp) /* fa */, %rdi
    call getc
    movl %eax, -186(%rbp) /* ch */
    cmpl $-1, -186(%rbp) /* ch */
    jne .WHILE_60_ENTER

.WHILE_60_END:
    leaq .LC14(%rip), %rdi
    call puts

    movq -8(%rbp) /* fa */, %rdi
    call fclose
.EXIT_SUCCESS:
    movl $0, %eax
    leave
    ret
// 这里相当于把append搞成static的了，因为没有.globl，也不需要.globl
.type append, @function
append:
    pushq %rbp
    movq %rsp, %rbp

    subq $32, %rsp
    // 分配局部变量
    // source: -8(%rbp) /* source */
    // dest: -16(%rbp) /* dest */
    // bytes: -24(%rbp) /* bytes */
    movq %rdi, -8(%rbp) /* source */
    movq %rsi, -16(%rbp) /* dest */
    jmp .WHILE_71_COMPARE
.WHILE_71_ENTER:
    leaq temp.0(%rip), %rdi
    movq $1, %rsi
    movq -24(%rbp) /* bytes */, %rdx
    movq -16(%rbp) /* dest */, %rcx
    call fwrite
.WHILE_71_INCR:
    // nothing to do
.WHILE_71_COMPARE:
    leaq temp.0(%rip), %rdi
    movq $1, %rsi
    movq $4096, %rdx
    movq -8(%rbp) /* source */, %rcx
    call fread
    movq %rax, -24(%rbp) /* bytes */
    cmpq $0, %rax
    jg .WHILE_71_ENTER

    leave
    ret

.type s_gets, @function
s_gets:
    pushq %rbp
    movq %rsp, %rbp

    // 得琢磨一下减多少
    // sizeof(st) + sizeof(n) + sizeof(ret_val) + sizeof(i) = 8 + 4 + 8 + 4 = 24
    subq $32, %rsp

    // 分配局部变量
    // st: -8(%rbp)
    // n: -12(%rbp)
    // ret_val: -20(%rbp)
    // i: -24(%rbp)
    movq %rdi, -8(%rbp) /* st */
    movl %esi, -12(%rbp) /* n */
    movl $0, -24(%rbp) /* i */
    // 这两句实际是没必要的
    movq -8(%rbp) /* st */, %rdi
    movl -12(%rbp) /* n */, %esi
    movq stdin(%rip), %rdx
    call fgets
    movq %rax, -20(%rbp) /* ret_val */

    cmpq $0, %rax
    je .EXIT
    jmp .WHILE_15_COMPARE
.WHILE_15_ENTER:
    incl -24(%rbp) /* i */
.WHILE_15_COMPARE:
    movq -8(%rbp) /* st */, %rdi
    movl -24(%rbp) /* i */, %eax
    cltq
    movb (%rdi, %rax, 1), %al
    cmpb $10, %al
    je .WHILE_15_BREAK
    cmpb $0, %al
    je .WHILE_15_BREAK
    jmp .WHILE_15_ENTER
.WHILE_15_BREAK:
    movq -8(%rbp) /* st */, %rdi
    movl -24(%rbp) /* i */, %eax
    cltq
    movb (%rdi, %rax, 1), %al
    cmpb $10, %al
    jne .WHILE_20_COMPARE
    movl -24(%rbp) /* i */, %eax
    cltq
    movb $0, (%rdi, %rax, 1)
    jmp .EXIT

.WHILE_20_COMPARE:
    call getchar
    cmpb $10, %al
    jne .WHILE_20_COMPARE
.EXIT:
    movq -20(%rbp) /* ret_val */, %rax
    movq %rbp, %rsp
    popq %rbp
    ret

.local temp.0
// 不太明白，后面有个32是什么意思，我给它去掉，看看会不会有问题
// .comm temp.0,4096,32
.comm temp.0,4096